package eMdP.classesBasiques;

import java.util.LinkedList;

import com.jme.bounding.BoundingBox;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.geometry.PhysicsBox;
import com.jmex.physics.material.Material;

import eMdP.gestors.GestorModels;

/**
 * Escenari és un Node que conté la part gràfica del terreny de Joc (Escenari), com la part descriptiva.
 * 
 * @author Peppino Coorp.
 *
 */
public class Escenari extends Node{
	private static final long serialVersionUID = 1L;
	
	private int id;
	private String nom;
	private String descripcio;
	private String model;
	private String fotoInicial;
	private StaticPhysicsNode nodeEstatic;
	
	private LinkedList<Vector3f> posBusties = new LinkedList<Vector3f>();
	private LinkedList<Vector3f> posPNJS = new LinkedList<Vector3f>();
	private LinkedList<Vector3f> posFurgonetes = new LinkedList<Vector3f>();
	private LinkedList<Vector3f> posJugadors = new LinkedList<Vector3f>();
	
	/**
	 * Constructor bàsic que assigna al escenari, un id, el nom i un node estàtic. Com que no assigna cap model crea un terreny estàndar
	 * @param nom El nom de l'Escenari
	 * @param id La id que té l'Escenari
	 * @param nodeEstatic El node encarregat de les Físiques estàtiques de l'Escenari
	 */
	/*public Escenari(int id,String nom,StaticPhysicsNode nodeEstatic) {
		super(nom);
		setId(id);
		setNom(nom);
		setNodeEstatic(nodeEstatic);
		this.nodeEstatic.setName("nodeEstatic"+nom);
		crearEscenariEstandar();
		
		
		nodeEstatic.generatePhysicsGeometry(true);
		this.attachChild(nodeEstatic);
	}
	
	/**
	 * Constructor bàsic que assigna al escenari, un id, el nom i un node estàtic. Com que no assigna cap model crea un terreny estàndar
	 * @param nom El nom de l'Escenari
	 * @param id La id que té l'Escenari
	 * @param nodeEstatic El node encarregat de les Físiques estàtiques de l'Escenari
	 */
	/*public Escenari(int id,String nom,String model,StaticPhysicsNode nodeEstatic) {
		super(nom);
		setId(id);
		setNom(nom);
		setNodeEstatic(nodeEstatic);
		this.nodeEstatic.setName("nodeEstatic"+nom);
		
		setModel(model);
		carregarModel(model);
		
		nodeEstatic.generatePhysicsGeometry(false);
		this.attachChild(nodeEstatic);
	}
	
	/**
	 * Constructor total que assigna al escenari totes les seves variables, un id, el nom, la descripció, la fotoInicial
	 * i la localització del model.
	 * @param nom El nom de l'Escenari
	 * @param model El model que representa gràficament l'Escenari
	 * @param descripcio La descripció de l'Escenari
	 * @param fotoInicial La foto que es veu en mida reduida per escollir l'Escenari
	 * @param nodeEstatic El node encarregat de les Físiques estàtiques de l'Escenari
	 */
	/*public Escenari(int id,String nom, String model,String descripcio, String fotoInicial,StaticPhysicsNode nodeEstatic) {
		super(nom);
		setId(id);
		setNom(nom);
		setModel(model);
		setDescripcio(descripcio);
		setFotoInicial(fotoInicial);
		setNodeEstatic(nodeEstatic);
		
		nodeEstatic.generatePhysicsGeometry(true);
		this.attachChild(nodeEstatic);
	}*/
	
	/**
	 * Aquesta és la classe que fem servir!!
	 * @param id
	 * @param nom
	 * @param descripcio
	 * @param numBus
	 * @param busties
	 * @param numPNjs
	 * @param posP
	 * @param numFu
	 * @param posFurgo
	 * @param numJugadors
	 * @param posJugadors
	 * @param nodeEstatic
	 */
	public Escenari(int id,String nom, String descripcio, int numBus,LinkedList<Vector3f> busties, int numPNjs, LinkedList<Vector3f> posP, int numFu, LinkedList<Vector3f> posFurgo, int numJugadors,LinkedList<Vector3f> posJugadors, StaticPhysicsNode nodeEstatic){
		super(nom);
		setId(id);
		setNom(nom);
		setDescripcio(descripcio);
		setPosBusties(busties);
		setPosPNJS(posP);
		setPosFurgonetes(posFurgo);
		setPosJugadors(posJugadors);
		
		setNodeEstatic(nodeEstatic);
		this.nodeEstatic.setName("nodeEstatic"+nom);
		
		setModel(id+".jme");
		
		/* El model i la foto inicial es diuen el numero de id de l'Escenari amb l'extensio .jpg */
		setFotoInicial(id+".jpg");
		
		String nomTmp;
		nomTmp = nom.toLowerCase();
		nomTmp = nomTmp.replace(" ","_");
		System.out.println("Nom de la pantalla: "+nomTmp);
		
		
		carregarModel(nomTmp+".3DS");
		//Box patata = new Box("patata",new Vector3f(0,-0.5f,0),80,0.2f,80);
		//nodeEstatic.attachChild(patata);
		this.attachChild(nodeEstatic);
		this.nodeEstatic.generatePhysicsGeometry(true);
	}
	

	/**
	 * @return l'id
	 */
	public int getId() {
		return id;
	}

	/**
	 * @param id l'id que assignem a l'Escenari
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @return el nom
	 */
	public String getNom() {
		return nom;
	}

	/**
	 * @param nom el nom que assignem a l'Escenari
	 */
	public void setNom(String nom) {
		this.nom = nom;
	}

	/**
	 * @return the descripcio
	 */
	public String getDescripcio() {
		return descripcio;
	}

	/**
	 * @param descripcio la descripció que assignem a l'Escenari
	 */
	public void setDescripcio(String descripcio) {
		this.descripcio = descripcio;
	}

	/**
	 * @return the numBusties
	 */
	public int getNumBusties() {
		return posBusties.size();
	}

	
	/**
	 * @return the numPNJS
	 */
	public int getNumPNJS() {
		return posPNJS.size();
	}

	
	/**
	 * @return the numFurgos
	 */
	public int getNumFurgos() {
		return posFurgonetes.size();
	}


	/**
	 * @return the numPersonatges
	 */
	public int getNumJugadors() {
		return posJugadors.size();
	}

	/**
	 * @return the posBusties
	 */
	public LinkedList<Vector3f> getPosBusties() {
		return posBusties;
	}

	/**
	 * @param posBusties the posBusties to set
	 */
	public void setPosBusties(LinkedList<Vector3f> posBusties) {
		this.posBusties = posBusties;
	}

	/**
	 * @return the posPNJS
	 */
	public LinkedList<Vector3f> getPosPNJS() {
		return posPNJS;
	}

	/**
	 * @param posPNJS the posPNJS to set
	 */
	public void setPosPNJS(LinkedList<Vector3f> posPNJS) {
		this.posPNJS = posPNJS;
	}

	/**
	 * @return the posFurgonetes
	 */
	public LinkedList<Vector3f> getPosFurgonetes() {
		return posFurgonetes;
	}

	/**
	 * @param posFurgonetes the posFurgonetes to set
	 */
	public void setPosFurgonetes(LinkedList<Vector3f> posFurgonetes) {
		this.posFurgonetes = posFurgonetes;
	}

	/**
	 * @return the posPersonatges
	 */
	public LinkedList<Vector3f> getPosJugadors() {
		return posJugadors;
	}

	/**
	 * @param posPersonatges the posPersonatges to set
	 */
	public void setPosJugadors(LinkedList<Vector3f> posJugadors) {
		System.out.println("asdfdasdfasdfasdfasdfasdf: "+posJugadors);
		this.posJugadors = posJugadors;
	}

	/**
	 * @return el model
	 */
	public String getModel() {
		return model;
	}

	/**
	 * @param model el model que assignem a l'Escenari
	 */
	public void setModel(String model) {
		this.model = model;
	}

	/**
	 * @return la fotoInicial
	 */
	public String getFotoInicial() {
		return fotoInicial;
	}

	/**
	 * @param fotoInicial La fotoInicial que assignem a l'Escenari
	 */
	public void setFotoInicial(String fotoInicial) {
		this.fotoInicial = fotoInicial;
	}

	/**
	 * @return the nodeEstatic
	 */
	public StaticPhysicsNode getNodeEstatic() {
		return nodeEstatic;
	}

	/**
	 * @param nodeEstatic the nodeEstatic to set
	 */
	public void setNodeEstatic(StaticPhysicsNode nodeEstatic) {
		this.nodeEstatic = nodeEstatic;
	}
	
	/* --------------------- Fi dels Getter/Setters --------------------------------*/
	
	/**
	 * Métode que crea un Escenari Estandar, que consiteix en una caixa que fa de terra, i una altre que fa d'obstacle.
	 */
	public void crearEscenariEstandar(){
		//Node terrain = new Node("terrain");
		
    	Box c = new Box("terra",new Vector3f(0,0,0),10,1,10);
    	c.setModelBound(new BoundingBox());
    	c.updateModelBound();  
    	
    	Box d = new Box("obstacle",new Vector3f(10,1,0),3,3,3);
    	d.setModelBound(new BoundingBox());
    	d.updateModelBound();
    	
    	nodeEstatic.attachChild(c);
    	nodeEstatic.attachChild(d);
    	 
    	 
	}
	
	private void carregarModel(String direccio){
		
		Node mentre = GestorModels.getEscenari(direccio,"");
		mentre.setModelBound(new BoundingBox());
		mentre.updateModelBound();
		mentre.updateWorldBound();
		System.out.println("Entrem despres del model world bound "+mentre.getChildren().size());
		 for(int i = 0; i< mentre.getChildren().size(); i++)
	     {
	        System.out.println("Nom del fill "+i+": "+mentre.getChild(i).getName());	
			 if(mentre.getChild(i).getName().contains("o_invis"))
	        	{
	        		System.out.println("Em entrat a crear la caixa de l'obstacle invisible!!!"+mentre.getChild(i).getName());
	        		
					/*PhysicsBox obstacle = nodeEstatic.createBox("obstacle"+i);
					mentre.getChild(i).updateWorldBound();
					System.out.println("bbox: "+mentre.getChild(i).getWorldBound());
					BoundingBox bbox = (BoundingBox) mentre.getChild(i).getWorldBound();
					     
					obstacle.getLocalScale().set( bbox.xExtent * 2, bbox.yExtent * 2, bbox.zExtent * 2 );
					obstacle.getLocalTranslation().set( bbox.getCenter() );
					
					System.out.println("obstacle "+i+" scale: "+obstacle.getLocalScale());
					
					this.nodeEstatic.attachChild(obstacle);
					*/
					// Anem a tornar-los invisibles
					((Node)mentre.getChild(i)).setCullHint(CullHint.Always);
	    			((Node)mentre.getChild(i)).setRenderQueueMode(Renderer.QUEUE_SKIP);
	        	}
	     }
     	this.nodeEstatic.attachChild(mentre);         
	}
	
	public void crearFisiques(){
		nodeEstatic.generatePhysicsGeometry();
	}
}
